home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 24 / CU Amiga Magazine's Super CD-ROM 24 (1998)(EMAP Images)(GB)(Track 1 of 2)[!][issue 1998-07].iso / CUCD / Programming / SWI / source / src / pl-data.h < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-07  |  7.2 KB  |  238 lines

  1. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2. Proposal for new Prolog data-structures.
  3.  
  4. Aim
  5. ===
  6.  
  7. Flexibel adaption to different memory model.   Possible  to make `clean'
  8. programs, i.e. programs that donot make assumptions on the memory model.
  9. The latter appears necessary on some systems to put Prolog into a DLL.
  10.  
  11. Fast comparison and checking. The hope  is   that  the  result will have
  12. comparable or better speed.
  13.  
  14. Approach
  15. ========
  16.  
  17.     * No direct pointers in Prolog machine words anymore
  18.  
  19.     * Tags in the low bits to exploit SPARC and possible other
  20.       machines fixed-width instruction, so masks can be loaded
  21.       in one instead of two instructions.
  22.  
  23.     * Explicit encoding of the `user' data-types in the word,
  24.       so PL_term_type() can be much faster.
  25.  
  26.     * Explicit encoding of the storage regime used, so more code
  27.       can be generic.
  28.  
  29. Types:
  30. ======
  31.  
  32. Sorted to standard order of terms:
  33.  
  34. Storage places:
  35.  
  36.     S    Static (global variable)
  37.     H    Heap
  38.     L    Local
  39.     G    Global
  40.     T    Trail
  41.     -    `In the variable'
  42.  
  43.           INDEX  STORAGE  L  G  H  T  S  -  I
  44. ----------------------------------------------------------------
  45. Var        0      -                    00
  46. Integer        1      HG-      10 01       00
  47. Float        2      HG       10 01
  48. Atom        3      HS          01    00
  49. String        4      HG       10 01
  50. List        5      HG       10 01
  51. Term        6      HG       10 01
  52. Reference    7      HLG   11 10 01
  53. ----------------------------------------------------------------
  54.  
  55. Adding 2 bits for the garbage collector, this adds up to 7-bits tag info,
  56. leaving us with 32-7 is 25 bits data, or:
  57.  
  58.     * Tagged ints from -16M to +16M
  59.     * 128 MB per memory area, assuming all data is 4-byte aligned.
  60.  
  61. Giving this, stacks can be freely shifted!
  62.  
  63. Bit layout
  64. ==========
  65.  
  66.     * Value are the top-bits, so extracting the value is just a
  67.       shift.
  68.  
  69.     * GC masks follow, so, as they are normally both 0, shifting
  70.       suffices for this too.
  71.  
  72.     * Type is the low 3-bits, so a simple mask yields the type.
  73.  
  74.     * Storage in bits 4 and 5
  75.  
  76. Indirect data
  77. =============
  78.  
  79.     * Using normal tag, but the storage-specifier is 0x3 (11).  Tag
  80.       is only INTEGER, STRING or FLOAT
  81.  
  82.     * Using value: size in words of the object * 4
  83.     
  84.     * String uses the low-order 2 bits for specifying the amount of
  85.       padding bytes (0-3, 0 means 4).
  86. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  87.  
  88. #include "pl-buffer.h"
  89.  
  90. #define LMASK_BITS    7        /* total # mask bits */
  91.  
  92. #define TAG_MASK    0x00000007L    /* mask for tag */
  93. #define TAG_VAR        0x00000000L    /* tag for variable (= 0L) */
  94. #define TAG_INTEGER    0x00000001L    /* Tagged or indirect integer */
  95. #define TAG_FLOAT    0x00000002L    /* Floating point number */
  96. #define TAG_ATOM    0x00000003L    /* an atom */
  97. #define TAG_STRING    0x00000004L    /* String */
  98. #define TAG_LIST    0x00000005L    /* List */
  99. #define TAG_COMPOUND    0x00000006L    /* Compound term */
  100. #define TAG_REFERENCE    0x00000007L    /* Reference pointer */
  101.  
  102.                     /* Trail tag-bits */
  103. #define TAG_TRAILMASK    0x00000000L    /* mask for tag */
  104. #define TAG_TRAILADDR    0x00000000L    /* Trail-only: address */
  105. #define TAG_TRAILVAL    0x00000001L    /* Trail-only: value */
  106.  
  107. #define STG_MASK    (0x3<<3)
  108. #define STG_STATIC    (0x0<<3)    /* storage masks */
  109. #define STG_GLOBAL    (0x1<<3)
  110. #define STG_LOCAL    (0x2<<3)
  111. #define STG_RESERVED    (0x3<<3)
  112.  
  113. #define STG_INLINE    STG_STATIC
  114. #define STG_TRAIL    STG_STATIC
  115.  
  116. #define MARK_MASK    (0x1<<5)    /* GC mark */
  117. #define FIRST_MASK    (0x2<<5)    /* GC first mark */
  118.  
  119. #define tag(w)        ((w) & TAG_MASK)
  120. #define storage(w)    ((w) & STG_MASK)
  121. #define valPtr2(w, s)    ((Word)(((w) >> 5) + base_addresses[s]))
  122. #define valPtr(w)    valPtr2(w, storage(w))
  123. #define valInt(w)    ((long)(w) >> 7)
  124.  
  125.          /*******************************
  126.          *      EXTENDED TAG        *
  127.          *******************************/
  128.  
  129. extern const unsigned int tagtypeex[];
  130.  
  131. #define tagex(w)    ((w) & (TAG_MASK|STG_MASK))
  132.  
  133. #define TAGEX_INDIRECT    0x1
  134. #define isIndirect(w)    (tagtypeex[tagex(w)] & TAGEX_INDIRECT)
  135.  
  136.          /*******************************
  137.          *     BASIC TYPE TESTS    *
  138.          *******************************/
  139.  
  140. #define isVar(w)    ((w) == 0L)    /* variable */
  141. #define isAtom(w)    (tag(w) == TAG_ATOM)
  142. #define isInteger(w)    (tag(w) == TAG_INTEGER)
  143. #define isReal(w)    (tag(w) == TAG_FLOAT)
  144. #define isString(w)    (tag(w) == TAG_STRING)
  145. #define isTerm(w)    (tag(w) == TAG_COMPOUND)
  146.  
  147.  
  148.          /*******************************
  149.          *        REFERENCES        *
  150.          *******************************/
  151.  
  152. #define isRef(w)    (tag(w) == TAG_REFERENCE)
  153. #define unRef(w)    ((Word)valPtr(w))
  154. #define deRef(p)    { while(isRef(*(p))) (p) = unRef(*(p)); }
  155. #define deRef2(p, d)    { (d) = (p); deRef(d); }
  156.  
  157.  
  158.          /*******************************
  159.          *    COMPOUNDS AND LISTS    *
  160.          *******************************/
  161.  
  162. #define functorTerm(w)    valueTerm(w)->definition
  163. #define arityTerm(w)    arityFunctor(valueTerm(w)->definition)
  164. #define valueTerm(w)    ((Functor)valPtr(w))
  165. #define hasFunctor(w,f) (isTerm(w) && valueTerm(w)->definition == (f))
  166. #define argTerm(w, n)    (((Functor)valPtr(w))->arguments[n])
  167. #define argTermP(w, n)    (&argTerm(w, n))
  168.  
  169. #define isList(w)    hasFunctor(w, FUNCTOR_dot2)
  170. #define isNil(w)    ((w) == ATOM_nil)
  171.  
  172.  
  173.          /*******************************
  174.          *          INDIRECTS        *
  175.          *******************************/
  176.  
  177. #define mkIndHdr(n, t)    (((n)<<9) | (t) | STG_LOCAL)
  178. #define wsizeofInd(iw)    ((iw)>>9)
  179. #define addressIndirect(w) valPtr(w)
  180. #define valIndirectP(w)    (((Word)valPtr(w))+1)
  181.  
  182. #define padHdr(iw)    (((iw)>>7 & 0x3) ? ((iw)>>7 & 0x3) : 4)
  183. #define mkPadHdr(n)    (((n)&(sizeof(word)-1)) << 7)
  184. #define mkStrHdr(n,p)    (mkIndHdr(n, TAG_STRING)|mkPadHdr(pad))
  185.  
  186. #define valString(w)    ((char *)valIndirectP(w))
  187. #define valBignum(w)    (*(long *)valIndirectP(w))
  188. #define isBignum(w)    (isInteger(w) && storage(w) != STG_INLINE)
  189. #define isTaggedInt(w)    (tagex(w) == (TAG_INTEGER|STG_INLINE))
  190.             /* == (isInteger(w) && storage(w) == STG_INLINE) */
  191.  
  192.          /*******************************
  193.          *           VALUES        *
  194.          *******************************/
  195.  
  196. #define indexAtom(w)    ((w)>>LMASK_BITS)
  197. #define atomValue(w)    fetchBuffer(&atom_array, indexAtom(w), Atom)
  198. #define stringAtom(w)    (atomValue(w)->name)
  199. #define valInteger(w)    (storage(w) == STG_INLINE ? valInt(w) : valBignum(w))
  200.  
  201.          /*******************************
  202.          *          FUNCTORS        *
  203.          *******************************/
  204.  
  205. #define F_ARITY_BITS    5        /* upto 32 inlined arity */
  206. #define F_ARITY_MASK    ((1<<F_ARITY_BITS)-1)
  207. #define MK_FUNCTOR(n, a) (((((n)<<F_ARITY_BITS)|(a))<<LMASK_BITS) | \
  208.               TAG_ATOM|STG_GLOBAL)
  209. #define functorHashValue(f, n)    ((f)>>(LMASK_BITS) & ((n)-1))
  210. #define indexFunctor(w)    ((w)>>(LMASK_BITS+F_ARITY_BITS))
  211. #define valueFunctor(w) fetchBuffer(&functor_array,indexFunctor(w),FunctorDef)
  212. #define _arityFunc_(w)    (((w) >> LMASK_BITS) & F_ARITY_MASK)
  213. #define arityFunctor(w) (_arityFunc_(w)!=F_ARITY_MASK ? _arityFunc_(w) \
  214.                               : valueFunctor(w)->arity)
  215. #define isAtomFunctor(w) (arityFunctor(w) == 0)
  216. #define nameFunctor(w)    (valueFunctor(w)->name)
  217.  
  218.          /*******************************
  219.          *      DERIVED TESTS        *
  220.          *******************************/
  221.  
  222. #define nonvar(w)    (!isVar(w))
  223. #define isNumber(w)    (isInteger(w) || isReal(w))
  224. #define isAtomic(w)    (!isVar(w) && !isTerm(w))
  225.  
  226.  
  227.          /*******************************
  228.          *       CREATING WORDS    *
  229.          *******************************/
  230.  
  231. #define MAXTAGGEDPTR    ((1L<<((8*sizeof(word))-5-1)) - 1)
  232.  
  233. #define consInt(n)    (((word)(n)<<7) | TAG_INTEGER)
  234. #if !O_DEBUG
  235. #define consPtr(p,ts)    ((word)((((word)(p)-base_addresses[(ts)&STG_MASK])<<5)|(ts)))
  236. #endif
  237.  
  238.